package tablero;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Iterator;

import titiritero.vista.Dibujable;
import ataques.Mina;
import barco.Barco;
import barco.Componente;

public class Tablero implements Serializable {
    private byte filas = 10;
    private byte columnas = 10;
    private ArrayList<Barco> barcos;
    private ArrayList<ArrayList<Casillero>> tablero;
    private ArrayList<Dibujable> vistasBarcos;

    public Tablero() {
        this.tablero = new ArrayList<ArrayList<Casillero>>();
        for (byte i = 0; i < this.filas; i++) {
            this.tablero.add(new ArrayList<Casillero>());
            for (byte j = 0; j < this.columnas; j++) {
                this.tablero.get(i).add(new Casillero());
            }
        }
        barcos = new ArrayList<Barco>();
        vistasBarcos = new ArrayList<Dibujable>();
    }

    public int cantidadBarcos() {
        return this.barcos.size();
    }

    public void addVista(Dibujable vistaBarco) {
        vistasBarcos.add(vistaBarco);
    }

    public Casillero getCasillero(Posicion posicion) {
        return this.tablero.get(posicion.getFila() - 1).get(posicion.getColumna() - 1);
    }

    public Rango getRango(Posicion posicion, int radio) {
        Rango rango = new Rango();
        for (int i = (radio * (-1)); i <= radio; i++) {
            for (int j = (radio * (-1)); j <= radio; j++) {
                if (((posicion.getFila() + i) > 0) && ((posicion.getFila() + i) < 11) && ((posicion.getColumna()) + j > 0) && ((posicion.getColumna() + j) < 11)) {
                    rango.agregarCasillero(this.tablero.get(posicion.getFila() + i - 1).get(posicion.getColumna() + j - 1));
                }
            }
        }
        return rango;
    }

    public ArrayList<Barco> getBarcos() {
        return barcos;
    }

    public byte getFilas() {
        return this.filas;
    }

    public byte getColumnas() {
        return this.columnas;
    }

    public void colocarBarcoVertical(Posicion posicion, Barco barco) {
        this.barcos.add(barco);
        ArrayList<Componente> componentes = barco.getPartes();
        Iterator<Componente> i = componentes.iterator();
        int contador = 0;
        while (i.hasNext()) {
            Componente componente = i.next();
            this.tablero.get(posicion.getFila() + contador - 1).get(posicion.getColumna() - 1).colocarComponente(componente);
            Posicion posicionAux = new Posicion(posicion.getFila() + contador, posicion.getColumna());
            componente.setPosicion(posicionAux);
            contador++;
        }
    }

    public void colocarBarcoHorizontal(Posicion posicion, Barco barco) {
        this.barcos.add(barco);
        ArrayList<Componente> componentes = barco.getPartes();
        Iterator<Componente> i = componentes.iterator();
        int contador = 0;
        while (i.hasNext()) {
            Componente componente = i.next();
            this.tablero.get(posicion.getFila() - 1).get(posicion.getColumna() + contador - 1).colocarComponente(componente);
            Posicion posicionAux = new Posicion(posicion.getFila(), posicion.getColumna() + contador);
            componente.setPosicion(posicionAux);
            contador++;
        }
    }

    private void sacarBarcosDeCasilleros() {
        Iterator<ArrayList<Casillero>> i = this.tablero.iterator();
        while (i.hasNext()) {
            Iterator<Casillero> iter = i.next().iterator();
            while (iter.hasNext()) {
                iter.next().getComponentes().clear();
            }
        }
    }

    public void actualizarMinas() {
        Iterator<ArrayList<Casillero>> i = this.tablero.iterator();
        while (i.hasNext()) {
            Iterator<Casillero> iter = i.next().iterator();
            while (iter.hasNext()) {
                Casillero casillero = iter.next();
                ArrayList<Mina> minas = casillero.getMinas();
                Iterator<Mina> it = minas.iterator();
                while (it.hasNext()) {
                    Mina mina = it.next();
                    mina.actualizarTiempoParaExplotar();
                    if (mina.listaParaExplotar(casillero.getComponentes().size())) {
                        Rango rango = new Rango();
                        rango = getRango(mina.getPosicion(), mina.getRadio());
                        rango.explotarMina(mina);
                        it.remove();
                    }
                }
            }
        }
    }

    public void moverBarcos() {
        sacarBarcosDeCasilleros();
        actualizarBarcosVivos();
        for (byte i = 0; i < this.barcos.size(); i++) {
            Barco barco = this.barcos.get(i);
            barco.verificarOrientacion(this.filas, this.columnas);
            barco.actualizarPosicionComponentes();
            ArrayList<Componente> partesBarco = barco.getPartes();
            for (byte j = 0; j < partesBarco.size(); j++) {
                Componente componente = partesBarco.get(j);
                this.tablero.get(componente.getPosicion().getFila() - 1).get(componente.getPosicion().getColumna() - 1).colocarComponente(componente);
            }
        }
    }

    private void actualizarBarcosVivos() {
        Iterator<Barco> itBarco = barcos.iterator();
        Iterator<Dibujable> itVista = vistasBarcos.iterator();
        while (itBarco.hasNext() && itVista.hasNext()) {
            Barco barco = itBarco.next();
            Dibujable dibujable = itVista.next();
            if (!barco.estaVivo()) {
                itBarco.remove();
                itVista.remove();
            }
        }

    }

    public ArrayList<ArrayList<Casillero>> getTablero() {
        return tablero;
    }

    public ArrayList<Dibujable> getVistasBarcos() {
        return vistasBarcos;
    }
}
